package com.yinxing.framework.shiro.jwt;

import com.yinxing.framework.constant.SysConstant;
import com.yinxing.framework.utils.IpUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.util.StringUtils;
import org.apache.shiro.web.filter.AccessControlFilter;
import org.apache.shiro.web.util.WebUtils;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@Slf4j
public class ShiroJwtTokenFilter extends AccessControlFilter {

    @Override
    protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) {
        final String token = getJwtTonke(request);
        final String userHost = IpUtils.getIpAddr((HttpServletRequest) request);
        final Subject subject = SecurityUtils.getSubject();

        //存在JwtToken 并且 当前用户为登录 则尝试自动登录
        if(StringUtils.hasLength(token) && !subject.isAuthenticated()) {
            try {
                subject.login(new JwtToken(token, userHost));
            } catch (Exception e) {
                log.warn("JwtToken自动登录失败:{{}}", e.getMessage());
                return false;
            }
        }
        return true;
    }

    @Override
    protected boolean onAccessDenied(ServletRequest request, ServletResponse response) {
        //JwtToken登录失败以后需要移除Http头中的Token字段
        HttpServletResponse httpResponse =  WebUtils.toHttp(response);
        httpResponse.setHeader(SysConstant.JWT_TOKEN_HTTP_HEADER, SysConstant.EMPTY_STRING);
        return true;
    }

    /**
     * 获取Http请求头中的JwtToken字段
     * @param request HttpServletRequest
     * @return JwtToken
     */
    private String getJwtTonke(ServletRequest request) {
        HttpServletRequest httpServletRequest = WebUtils.toHttp(request);
        return httpServletRequest.getHeader(SysConstant.JWT_TOKEN_HTTP_HEADER);
    }

}
